#include "sentencetest.h"
#include "core/sentence.h"

SentenceTest::SentenceTest(QObject *parent) :
    QObject(parent),
	rsentence(NULL),
	lsentence(NULL)
  {
  }

void SentenceTest::initTestCase()
  {
  rsentence = new Sentence();
  lsentence = new Sentence();
  }

void SentenceTest::cleanupTestCase()
  {
  delete rsentence;
  delete lsentence;
  }

void SentenceTest::testComparison_data()
  {
  QTest::addColumn<QString>("left");
  QTest::addColumn<QString>("right");
  QTest::addColumn<bool>("comparison");

  QTest::newRow("1") << "delta(2,3)" << "delta(2,3)" << true;
  QTest::newRow("2") << "delta(3,3)" << "-delta(2,3)" << false;
  QTest::newRow("3") << "f(x)" << "f(y)" << false;
  }

void SentenceTest::testComparison()
  {
  QFETCH(QString, left);
  QFETCH(QString, right);
  QFETCH(bool, comparison);

  translator.stringToSentence(left, *lsentence);
  translator.stringToSentence(right, *rsentence);

  bool tmp = (*lsentence == *rsentence);
  QCOMPARE(tmp, comparison);

  }

void SentenceTest::testBasicConcatenate_data()
  {
  QTest::addColumn<QString>("leftSentence");
  QTest::addColumn<QString>("rightSentence");
  QTest::addColumn<QString>("concatenated");

  QTest::newRow("1") << "delta(x,y)" << "a_z" << "delta(x,y) a_z";
  QTest::newRow("2") << "a_i b_c" << "a_b" << "a_i b_c a_b";
  QTest::newRow("3") << "a_i b_c" << "a_b delta(x,y)" << "a_i b_c a_b delta(x,y)";
  }

void SentenceTest::testBasicConcatenate()
  {
  QFETCH(QString, leftSentence);
  QFETCH(QString, rightSentence);
  QFETCH(QString, concatenated);

  translator.stringToSentence(leftSentence, *lsentence);
  translator.stringToSentence(rightSentence, *rsentence);
  lsentence->concatenate(*rsentence);
  QString result = translator.sentenceToString(*lsentence);

  QCOMPARE(result, concatenated);
  }

void SentenceTest::testSortDeltas_data()
  {
  QTest::addColumn<QString>("input");
  QTest::addColumn<QString>("output");
  QTest::addColumn<bool>("changed");

  QTest::newRow("1") << "a_z delta(x,y)" << "a_z delta(x,y)" << false;
  QTest::newRow("2") << "a_i x y delta(x,y) delta(a,z) function(k)" << "a_i x y delta(a,z) delta(x,y) function(k)" << true;
  QTest::newRow("3") << "x y delta(x,y) delta(a,z) function(k)" << "x y delta(a,z) delta(x,y) function(k)" << true;
  QTest::newRow("4") << "delta(aa,y) delta(a,z) function(k)" << "delta(a,z) delta(aa,y) function(k)" << true;
  QTest::newRow("5") << "delta(a,y) delta(a,x)" << "delta(a,x) delta(a,y)" << true;
  QTest::newRow("6") << "x y delta(a,b) w z " << "x y delta(a,b) w z" << false;
  QTest::newRow("7") << "delta(a,x) delta(c,a)" << "delta(a,c) delta(a,x)" << true;
  QTest::newRow("8") << "delta(a,c) delta(a,x)" << "delta(a,c) delta(a,x)" << false;
  }

void SentenceTest::testSortDeltas()
  {
  QFETCH(QString, input);
  QFETCH(QString, output);
  QFETCH(bool, changed);

  translator.stringToSentence(input, *lsentence);
  int firstDeltaIndex = lsentence->firstOccurrenceOfType(Word::WT_DELTA);
  int deltaCount = lsentence->countWordType(Word::WT_DELTA);
  bool resChanged = lsentence->sortType(firstDeltaIndex, deltaCount, Word::WT_DELTA);
  QString result = translator.sentenceToString(*lsentence);
  QCOMPARE(result, output);
  QCOMPARE(resChanged, changed);
  }

void SentenceTest::testSortVariables_data()
  {
  QTest::addColumn<QString>("input");
  QTest::addColumn<QString>("output");

  QTest::newRow("1") << "b a" << "a b";
  QTest::newRow("2") << "b a 2" << "2 a b";
  QTest::newRow("3") << "a_i x y delta(x,y) function(k)" << "a_i x y delta(x,y) function(k)";
  QTest::newRow("4") << "2 a_i z aa delta(x,y) function(k)" << "2 a_i aa z delta(x,y) function(k)";
  QTest::newRow("5") << "2 a_i z aa z a z z(x,y) z(k)" << "2 a_i a aa z z z z(x,y) z(k)";
  QTest::newRow("6") << "c a" << "a c";
  QTest::newRow("7") << "a" << "a";
  QTest::newRow("8") << "c_i a" << "c_i a";
  QTest::newRow("9") << "aa z a" << "a aa z";
  }

void SentenceTest::testSortVariables()
  {
  QFETCH(QString, input);
  QFETCH(QString, output);

  translator.stringToSentence(input, *lsentence);
  int firstVariableIndex = lsentence->firstOccurrenceOfType(Word::WT_VARIABLE);
  int variableCount = lsentence->countWordType(Word::WT_VARIABLE);
  lsentence->sortType(firstVariableIndex, variableCount, Word::WT_VARIABLE);
  QString result = translator.sentenceToString(*lsentence);
  QCOMPARE(result, output);
  }

void SentenceTest::testSortFunctions_data()
  {
  QTest::addColumn<QString>("input");
  QTest::addColumn<QString>("output");

  QTest::newRow("1") << "function(z,x) function(a)" << "function(a) function(z,x)";
  QTest::newRow("2") << "agh(h) abc(a)" << "abc(a) agh(h)";
  QTest::newRow("3") << "a_i agh(h) def(a) abc(a)" << "a_i abc(a) agh(h) def(a)";
  QTest::newRow("4") << "a_i abc(b) agh(h) def(a) abc(a)" << "a_i abc(a) abc(b) agh(h) def(a)";
  }

void SentenceTest::testSortFunctions()
  {
  QFETCH(QString, input);
  QFETCH(QString, output);

  translator.stringToSentence(input, *lsentence);
  int firstFunctionIndex = lsentence->firstOccurrenceOfType(Word::WT_FUNCTION);
  int functionsCount = lsentence->countWordType(Word::WT_FUNCTION);
  lsentence->sortType(firstFunctionIndex, functionsCount, Word::WT_FUNCTION);
  QString result = translator.sentenceToString(*lsentence);
  QCOMPARE(result, output);
  }

void SentenceTest::testDoDeltaTrick_data()
  {
  QTest::addColumn<QString>("input");
  QTest::addColumn<QString>("output");

  QTest::newRow("1") << "delta(a,x) delta(c,x)" << "delta(a,c) delta(a,x)";
  QTest::newRow("2") << "delta(x,y) delta(a,b) d_b" << "delta(a,b) delta(x,y) d_a";
  QTest::newRow("3") << "a delta(a,x) delta(c,x) a_x a_a" << "a delta(a,c) delta(a,x) a_a a_a";
  QTest::newRow("4") << "x y delta(x,y) delta(a,z) function(k)" << "x y delta(a,z) delta(x,y) function(k)";
  QTest::newRow("5") << "a_b a_b a_c delta(i,j) delta(a,a)" << "a_b a_b a_c delta(a,a) delta(i,j)";
  QTest::newRow("6") << "a_b a_b" << "a_b a_b";
  }

void SentenceTest::testDoDeltaTrick()
  {
  QFETCH(QString, input);
  QFETCH(QString, output);

  translator.stringToSentence(input, *lsentence);
  lsentence->doDeltaTrick();
  QString result = translator.sentenceToString(*lsentence);
  QCOMPARE(result, output);
  }

void SentenceTest::testSortAllTypesInSentence_data()
  {
  QTest::addColumn<QString>("input");
  QTest::addColumn<QString>("output");

  QTest::newRow("1") << "b a" << "a b";
  QTest::newRow("2") << "b a 2" << "2 a b";
  QTest::newRow("3") << "a_i x y delta(x,y) function(k)" << "x y delta(x,y) function(k) a_i";
  QTest::newRow("4") << "delta(d,e) x a_i y delta(a,b) 2 function(k)" << "2 x y delta(a,b) delta(d,e) function(k) a_i";
  QTest::newRow("5") << "fun(a) delta(d,e) x function(k) a_i y delta(a,b) 2 " << "2 x y delta(a,b) delta(d,e) fun(a) function(k) a_i";
  }

void SentenceTest::testSortAllTypesInSentence()
  {
  QFETCH(QString, input);
  QFETCH(QString, output);

  translator.stringToSentence(input, *lsentence);
  lsentence->groupTypes();

  QString result = translator.sentenceToString(*lsentence);
  QCOMPARE(result, output);
  }


void SentenceTest::testGetCommonPart_data()
  {
  QTest::addColumn<QString>("leftSentence");
  QTest::addColumn<QString>("rightSentence");
  QTest::addColumn<QString>("commonPart");

  QTest::newRow("1") << "3 delta(x,y)" << "3 delta(x,y)" << "3 delta(x,y)";
  QTest::newRow("2") << "a_i b_c" << "b_c" << "b_c";
  QTest::newRow("3") << "2 a_i b_c" << "4 a_b a_i b_c delta(x,y)" << "2 a_i b_c";
  QTest::newRow("4") << "delta(x,y) a c" << "b delta(x,y)" << "delta(x,y)";
  }

void SentenceTest::testGetCommonPart()
  {
  QFETCH(QString, leftSentence);
  QFETCH(QString, rightSentence);
  QFETCH(QString, commonPart);

  translator.stringToSentence(leftSentence, *lsentence);
  translator.stringToSentence(rightSentence, *rsentence);
  Sentence commonSentence;
  lsentence->getCommonPart(*rsentence, commonSentence);
  QString result = translator.sentenceToString(commonSentence);

  QCOMPARE(result, commonPart);
  }
